/**
 * This is a keyboard for calculator application
 * 
 * 
 */
 // Declare global variables
var result = "";
var numbers = new Array();
var operators = new Array();
var tmpString = "";
var countOfPoint = 0;
var countOfOperator = 0;
var OPERATORS = "+-*/=";
var calFlag = true;

/**
 * Init the program
 * 
 */
function init() {
	// Clear Screen
	document.Screen.Display.value = "";

	// Initialize variables' value
	result = "";
	numbers = new Array();
	operators = new Array();
	tmpString = "";
	countOfPoint = 0;
	countOfOperator = 0;
	OPERATORS = "+-*/=";
	calFlag = true;
}

/**
 * Clear
 * 
 */
function clear() {
	init();
}

/**
 * keyNumb cares out the calculator's button action
 * 
 * @param null
 */
function keyNum() {

	if (!calFlag) {
		return;
	}

	// Get source event
	var src = window.event.target;

	// Get key value
	var keyValue = src.innerHTML;

	// Get the typed number
	if (OPERATORS.indexOf(keyValue, 0) > -1) {
		if (countOfOperator == 0 && tmpString.length > 0) {
			// Convert String to long
			numbers[numbers.length] = parseFloat(tmpString);
			
			// Handle the operator
			if (keyValue != "=") {
				operators[operators.length] = keyValue;
			}

			// clear tmpString
			tmpString = "";

			// clear count of point
			countOfPoint = 0;

			// set count of operator
			countOfOperator = 1;

			// Set display
			result = "";
			for ( var i = 0; i < numbers.length; i++) {
				result = result + numbers[i];
				if (i < operators.length) {
					result = result + " " + operators[i] + " ";
				}
			}
		}
	} else {
		// Continue to get typed number
		// A number has only one sign of "."
		if (keyValue != "." || countOfPoint < 1) {
			tmpString = tmpString + keyValue;

			// Clear count of operator
			countOfOperator = 0;

			// Set result for display
			result = result + keyValue;

			if (keyValue == ".") {
				countOfPoint = 1;
			}
		}
	}

	// Display value
	document.Screen.Display.value = result;
}

/**
 * Calculate the value
 * 
 * @param result
 *            the string of terms and operators
 */
function calculate() {
	if (!calFlag) {
		init();
		setElementText(window.event.target, "=");
		return;
	}
	
	keyNum();

	if (numbers.length >= operators.length)
	{
		// Multiple and divide are performed first
		for ( var i = 0; i < operators.length; i++) {
			if (operators[i] == "*") {
				numbers[i] = numbers[i] * numbers[i + 1];
				i = calculateHelper(i);
			} else if (operators[i] == "/") {
				numbers[i] = numbers[i] / numbers[i + 1];
				i = calculateHelper(i);
			}
		}

		// Then addition and subtraction are performed late
		for ( var i = 0; i < operators.length; i++) {
			if (operators[i] == "+") {
				numbers[i] += numbers[i + 1];
				i = calculateHelper(i);
			} else if (operators[i] == "-") {
				numbers[i] -= numbers[i + 1];
				i = calculateHelper(i);
			}
		}

		result = result + " = " + numbers[0];
	}

	// Display value
	document.Screen.Display.value = result;
	
	// set clear
	calFlag = false;
	setElementText(window.event.target, "CLEAR");
}

/**
 * Set element text
 *
 */
function setElementText(src, text) {
	src.innerHTML = text;
}

/**
 * Calculating helper
 * 
 * @param index
 *            the index
 */
function calculateHelper(index) {
	var i = index;
	numbers = arrayCut(numbers, i + 1, 1); // Remove numbers[i + 1]
	operators = arrayCut(operators, i, 1); // Remove operators[i]
	return (index - 1); // Return to previous position
}

/**
 * Remove a element in a array
 *
 *
 */
function arrayCut(array, i, n) {
	if (n > 0 && i > -1 && i < array.length) {
		if ((i + n) < array.length ) {
			for(; i + n < array.length; i++) {
				array[i] = array[i + n];
			}
		
			while(n > 0) {
				n--;
				array.pop();
			}	
		} else {
			while(i < array.length) {
				array.pop();
				i++;
			}
		}
	}
	
	return array;
}

/**
 * Check if an array of string contain the element text
 * 
 * @param stringArray
 *            array for checking
 * @param text
 *            the being checked text
 * @returns {Boolean}
 */
function arrayContain(stringArray, text) {
	for ( var i = 0; i < stringArray.length; i++) {
		if (stringArray[i] == text) {
			return true;
		}
	}

	return false;
}

/**
 * Make table be stripy
 * 
 * @param theClass
 *            the table's ID
 */
function stripyTable(theClass) {
	rows = document.getElementsByTagName("tr");
	for ( var i = 0; i < rows.length; i++) {
		addClass(rows[i], theClass);
	}
}

/**
 * Check out a element having a class
 * 
 * @param target
 *            the Element
 * @param theClass
 *            the class name in string
 * @returns {Boolean} return True if having
 */
function hasClass(target, theClass) {
	var pattern = new RegExp("(^| )" + theClass + "( |$)");
	if (pattern.test(target.className)) {
		return true;
	}
	return false;
};

/**
 * Add class attribute to a element
 * 
 * @param target
 *            the element
 * @param theClass
 *            the class
 * @returns null
 */
function addClass(target, theClass) {
	if (!hasClass(target, theClass)) {
		if (target.className == "") {
			target.className = theClass;
		} else {
			target.className += " " + theClass;
		}
	}
};

/**
 * Change the label of a element if known it's ID
 * 
 * @param buttonId
 *            the id of a button
 * @param text
 *            the text for new button's label text
 */
function replaceButtonText(buttonId, text) {
	if (document.getElementById) {
		var button = document.getElementById(buttonId);
		if (button) {
			if (button.childNodes[0]) {
				// alert("ch");
				button.childNodes[0].nodeValue = text;
			} else if (button.value) {
				// alert("val");
				button.value = text;
			} else // if (button.innerHTML)
			{
				// alert("inner");
				button.innerHTML = text;
			}
		}
	}
}